
#include <iostream>
#include <functional>
#include <string>
#include <vector>
#include <algorithm>

typedef std::function<int(int)> callback;
struct my_struct {
    callback cb;
    int value;
};



void test_func(my_struct my) {
    my.value = my.cb(33);
    std::cout << my.value << std::endl;
};

int test_add(int i, int j) {
    return i+j;
};

void test_case1() {
    my_struct my;
    my.cb = std::bind(test_add, std::placeholders::_1, 20);
    test_func(my);
    std::cout << my.cb(22) << std::endl;
}

class dummy_class {
    public :
        int test_mul(int i, int j) { return i*j;}
        void test_dummy(int i) { std::cout << "test dummy - " << i << std::endl;}
};

typedef std::function<void(int)> callback2;


void test_case2() {

    dummy_class d1;
    auto  cb = std::bind(&dummy_class::test_dummy, &d1, 100);
    cb();

    callback2 cb2 = std::bind(&dummy_class::test_dummy, &d1, std::placeholders::_1);
    cb2(101);
}

class Person {
    private:
        std::string name;
    public:
        Person(const std::string& n) : name(n) {}
        void print() const {
            std::cout << name << std::endl;
        }
        void print2(const std::string& prefix) const {
            std::cout << prefix << name << std::endl;
        }
};

void test_case3() {

    std::vector<Person> coll = { Person("Tick"), Person("Trick"), Person("Track")};
    std::for_each(coll.begin(), coll.end(), std::bind(&Person::print, std::placeholders::_1));
    
}

int main() {
    //test_case1();
    //test_case2();
    test_case3();
    return 0;
}